package com.thinkit.cms.service.filesource;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import com.thinkit.cms.api.filesource.WebStaticFileService;
import com.thinkit.cms.api.site.SiteService;
import com.thinkit.cms.dto.template.TemplateDto;
import com.thinkit.core.base.BaseContextKit;
import com.thinkit.core.constant.Constants;
import com.thinkit.utils.model.ApiResult;
import com.thinkit.utils.model.FileViewModel;
import com.thinkit.utils.properties.ThinkItProperties;
import com.thinkit.utils.utils.Checker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class WebStaticFileServiceImpl implements WebStaticFileService {

    @Autowired
    SiteService siteService;

    @Autowired
    ThinkItProperties thinkItProperties;

    @Override
    public List<FileViewModel> listPage(String path) {
        String domain = siteService.getDomain(null,BaseContextKit.getSiteId());
        List<FileViewModel> fileInfoModels = new ArrayList<>();
        if(Checker.BeNotBlank(domain)){
            String finalPath = thinkItProperties.getSitePath().replace(Constants.FILE_PATH_DOUBLE_BACKLASH,Constants.SEPARATOR)+Constants.SEPARATOR+domain;
            System.out.println("文件路径============================："+finalPath);
            if(Checker.BeNotBlank(path)) finalPath+=Constants.SEPARATOR +path;
            File[] files =FileUtil.ls(finalPath);
            if(Checker.BeNotEmpty(files)){
                int i=0;
                for(File file:files){
                    if(i%9==0){
                        if(Checker.BeNotBlank(path)){
                            FileViewModel viewModel = new FileViewModel("返回上一级",false);
                            viewModel.setRelativePath(path.substring(0,path.lastIndexOf("/")));
                            fileInfoModels.add(viewModel);
                        }
                    }
                    Path pathInfo= Paths.get(file.getAbsolutePath());
                    BasicFileAttributeView basicview= Files.getFileAttributeView(pathInfo, BasicFileAttributeView.class);
                    FileViewModel fileInfoModel = null;
                    try {
                        fileInfoModel = new FileViewModel(file.getName(),file.isDirectory(),basicview.readAttributes());
                        fileInfoModel.setRelativePath(path+Constants.SEPARATOR+file.getName());
                        fileInfoModels.add(fileInfoModel);
                    } catch (IOException e) {
                        log.error(e.getMessage());
                    }
                    i++;
                }
                return fileInfoModels;
            }
        }
        FileViewModel viewModel = new FileViewModel("返回上一级",false);
        viewModel.setRelativePath(path.substring(0,path.lastIndexOf("/")));
        fileInfoModels.add(viewModel);
        return fileInfoModels;
    }

    @Override
    public ApiResult getFileContent(String filePath) {
        String domain = siteService.getDomain(null,BaseContextKit.getSiteId());
        if(Checker.BeNotBlank(domain)){
            String finalPath = thinkItProperties.getSitePath().replace(Constants.FILE_PATH_DOUBLE_BACKLASH,Constants.SEPARATOR)+Constants.SEPARATOR+domain+filePath;
            File file = new File(finalPath);
            if(file.exists()){
                String fileContent = FileUtil.readString(file, Constants.DEFAULT_CHARSET_NAME);
                return ApiResult.result(fileContent);
            }
        }
        return ApiResult.result("");
    }


    @Override
    public ApiResult setFileContent(String filePath, String content) {
        String domain = siteService.getDomain(null,BaseContextKit.getSiteId());
        if(Checker.BeNotBlank(domain)){
            String finalPath = thinkItProperties.getSitePath().replace(Constants.FILE_PATH_DOUBLE_BACKLASH,Constants.SEPARATOR)+Constants.SEPARATOR+domain+filePath;
            File file = new File(finalPath);
           if(file.exists()){
               content = Checker.BeNotNull(content)?content:"";
               FileUtil.writeString(content,file, Charset.forName("UTF-8"));
           }else{
               ApiResult.result(5055);
           }
        }
        return ApiResult.result();
    }

    @Override
    public ApiResult deleteFile(String filePath) {
        String domain = siteService.getDomain(null,BaseContextKit.getSiteId());
        if(Checker.BeNotBlank(domain)){
            String finalPath = thinkItProperties.getSitePath().replace(Constants.FILE_PATH_DOUBLE_BACKLASH,Constants.SEPARATOR)+Constants.SEPARATOR+domain+filePath;
            File file = new File(finalPath);
            recursionDeleteFile(file);
        }
        return ApiResult.result();
    }

    private void recursionDeleteFile(File file) {
        if (file.isFile()) {
            file.delete();
        } else {
            File[] files = file.listFiles();
            for (File f : files) {
                if (f.isDirectory()) {
                    recursionDeleteFile(f);
                } else {
                    f.delete();
                }
            }
            file.delete();
        }

    }

    @Override
    public void saveTemp(TemplateDto templateDto) {

    }

    @Override
    public void downZip(String path, HttpServletResponse response) {
        String ZIP = ".zip";
        String domain = siteService.getDomain(null,BaseContextKit.getSiteId());
        String basePath = thinkItProperties.getSitePath().replace(Constants.FILE_PATH_DOUBLE_BACKLASH,Constants.SEPARATOR)+Constants.SEPARATOR+domain;
        String finalPath = basePath+path;
        if(FileUtil.exist(finalPath)){
            String fileName = path.substring(path.lastIndexOf("/"),path.length());
            fileName= Checker.BeNotEmpty(fileName) ? fileName+ZIP : System.currentTimeMillis()+ZIP;
            String zipFilePath = basePath+fileName;
           try {
               ZipUtil.zip(finalPath, zipFilePath, true);
               down(zipFilePath,response);
           }catch (Exception e){
               log.error(e.getMessage());
           }finally {
               FileUtil.del(zipFilePath);
           }
        }
    }

    private File down(String filePath,HttpServletResponse response) throws IOException {
        File file = new File(filePath);
        if(file.exists()){
            InputStream in = null;
            OutputStream out = null;
            response.setCharacterEncoding(Constants.DEFAULT_CHARSET_NAME);
            response.setHeader("content-disposition","attachment;fileName="+file.getName());
            response.setHeader("FileName", file.getName());
            response.setHeader("Access-Control-Expose-Headers", "FileName");
            try {
                out=  response.getOutputStream();
                in = new FileInputStream(file);
                byte[] buffer  = new byte[1024];
                int i=in.read(buffer );
                while (i!=-1){
                    out.write(buffer , 0, i);//将缓冲区的数据输出到浏览器
                    i= in.read(buffer );
                }
            } catch (IOException e) {
                throw e;
            }finally {
                in.close();
                out.close();
            }
        }
        return file;
    }

    @Override
    public void importFile(MultipartFile multipartFile, Integer type) {

    }

    @Override
    public ApiResult uploadFile(List<MultipartFile> files, String filePath) {
        if(Checker.BeNotEmpty(files)){
            String domain = siteService.getDomain(null,BaseContextKit.getSiteId());
            if(Checker.BeNotBlank(domain)){
                String finalPath = thinkItProperties.getSitePath().replace(Constants.FILE_PATH_DOUBLE_BACKLASH,Constants.SEPARATOR)+
                Constants.SEPARATOR+domain+filePath+Constants.SEPARATOR;
                File file = new File(finalPath);
                if(file.exists() && file.isDirectory()){
                    for(MultipartFile mfile:files){
                        try {
                            FileUtil.writeFromStream(mfile.getInputStream(),finalPath+mfile.getOriginalFilename());
                        } catch (IOException e) {
                           return ApiResult.result();
                        }
                    }
                }
            }
        }
        return ApiResult.result();
    }

    @Override
    public ApiResult createFile(String filePath, String folderName)  {
        if(!isValidFileName(folderName)){
            return ApiResult.result(5044);
        }
        String domain = siteService.getDomain(null,BaseContextKit.getSiteId());
        String finalPath = thinkItProperties.getSitePath().replace(Constants.FILE_PATH_DOUBLE_BACKLASH,Constants.SEPARATOR)+
        Constants.SEPARATOR+domain+filePath+Constants.SEPARATOR;
        if(FileUtil.exist(finalPath)){
            FileUtil.newFile(finalPath+folderName).mkdir();
            return ApiResult.result();
        }
        return ApiResult.result(20000);
    }

    public static boolean isValidFileName(String fileName) {
        if(Checker.BeBlank(fileName)){
          return false;
        }else{
            Pattern pattern = Pattern.compile("[\\s\\\\/:\\*\\?\\\"<>\\|]");
            Matcher matcher = pattern.matcher(fileName);
            fileName= matcher.replaceAll(""); // 将匹配到的非法字符以
            return fileName.matches("[^\\s\\\\/:\\*\\?\\\"<>\\|](\\x20|[^\\s\\\\/:\\*\\?\\\"<>\\|])*[^\\s\\\\/:\\*\\?\\\"<>\\|\\.]$");
        }
    }
}
